/*
 * RtpTcpParser.cpp
 *
 *  Created on: 2018年12月14日
 *      Author: terry
 */

#include "RtpTcpParser.h"
#include "TStringUtil.h"

#include "H264RtpUnPacker.h"
#include "H265RtpUnPacker.h"
#include "CRtpUnPacker.h"
#include "RtpHeader.h"
#include <iostream>

RtpTcpParser::RtpTcpParser():
	m_file(),
	m_prefix(4)
{

}

RtpTcpParser::~RtpTcpParser() 
{
	close();
}

bool RtpTcpParser::open(const std::string& filepath, int prefix, const std::string& codec)
{
	fopen_s(&m_file, filepath.c_str(), "rb");
	if (m_file == NULL)
	{
		return false;
	}

	if (prefix == 2)
	{
		m_prefix = 2;
	}
	else
	{
		m_prefix = 4;
	}

	av::MediaCodec mcodec = av::MEDIA_CODEC_RAW;
	if (comn::StringUtil::icompare(codec, "h264") == 0)
	{
		m_unpacker.reset(new av::H264RtpUnPacker());
	}
	else if(comn::StringUtil::icompare(codec, "h265") == 0)
	{
		m_unpacker.reset(new av::H265RtpUnPacker());
	}
	else
	{
		m_unpacker.reset(new av::CRtpUnPacker());
	}

	m_unpacker->open(av::MEDIA_TYPE_VIDEO, mcodec);

	return true;
}

void RtpTcpParser::close()
{
	if (m_file)
	{
		fclose(m_file);
		m_file = NULL;
	}
}

bool RtpTcpParser::isOpen()
{
	return (m_file != NULL);
}

bool RtpTcpParser::readPacket(av::MediaPacket& pkt)
{
	bool found = false;
	av::RtpPacket rtpPacket;
	while (readRtpPacket(rtpPacket))
	{
		if (m_unpacker->unpack(rtpPacket, pkt))
		{
			found = true;
			break;
		}
	}
	return found;
}

bool RtpTcpParser::readRtpPacket(av::RtpPacket& pkt)
{
	int32_t length = 0;
	if (m_prefix == 2)
	{
		int16_t size = 0;
		size_t count = fread(&size, 1, sizeof(size), m_file);
		if (count != sizeof(size))
		{
			return false;
		}

		size = ntohs(size);
		length = size;
	}
	else
	{
		int32_t size = 0;
		size_t count = fread(&size, 1, sizeof(size), m_file);
		if (count != sizeof(size))
		{
			return false;
		}

		size = ntohs(size);
	}

	RTP_FIXED_HEADER header = RTP_FIXED_HEADER();
	size_t count = fread(&header, 1, sizeof(RTP_FIXED_HEADER), m_file);
	if (count != sizeof(header))
	{
		return false;
	}

	if (header.version != 2)
	{
		printf("invalid rtp version. %d\n", header.version);
		return false;
	}

	length -= sizeof(header);
	m_buffer.ensure(length);

	count = fread(m_buffer.data(), 1, length, m_file);
	if (count != length)
	{
		return false;
	}

	pkt.data = m_buffer.data();
	pkt.size = length;
	pkt.pt = header.payload;
	pkt.mark = header.marker;
	pkt.ts = ntohl(header.timestamp);
	pkt.seq = ntohs(header.seq_no);
	pkt.ssrc = ntohl(header.ssrc);
	

	printf("rtp. pt: %d, seq:%d, mark: %d, extension:%d, ts: %d, ssrc: %d, payload size: %d\n",
		pkt.pt, pkt.seq, pkt.mark, header.extension, pkt.ts, pkt.ssrc, pkt.size);

	return true;
}